package com.bmft.project02;
import java.io.IOException;

/**
 * @author 嘉文
 */
public class InfixToPostfix {
    public String infixToPostfix(String infix) {
        //init stack
        MyStack myStack = new MyStack(infix.length());
        //postfix.
        StringBuilder postfix = new StringBuilder();
        int length = infix.length();
        for (int i = 0; i < length; i++) {
            char tempChar;
            char charAt = infix.charAt(i);
            switch (charAt) {
                //左括号直接入栈，不用过多解释
                case '(':
                    myStack.push(charAt);
                    break;
                //如果遇到 +-，低级会导致一次出栈.
                case '+':
                case '-':
                    //出栈
                    while (!myStack.isEmpty()) {
                        tempChar = myStack.pop();
                        if (tempChar == '(') {
                            myStack.push(tempChar);
                            break;
                        }
                        postfix.append(" ").append(tempChar);
                    }
                    myStack.push(charAt);
                    break;
                case '*':
                case '/':
                    while (!myStack.isEmpty()){
                        tempChar = myStack.pop();
                        if (tempChar == '('||tempChar == '+' ||tempChar == '-') {
                            myStack.push(tempChar);
                            break;
                        }
                        postfix.append(" ").append(tempChar);
                    }
                    myStack.push(charAt);
                    break;
                case ')':
                    while (!myStack.isEmpty()){
                        tempChar = myStack.pop();
                        if (tempChar != '('){
                            postfix.append(" ").append(tempChar);
                        }else {
                            break;
                        }
                    }
                    break;
                default:
                    postfix.append(" ").append(charAt);
                    //if length enough
                    if (i<length-1){
                        int j = i + 1;
                        char nextNumber = infix.charAt(j);
                        while ((nextNumber+"").matches("^[0-9]*")&&j<length){
                            postfix.append(nextNumber);
                            nextNumber = infix.charAt(++j);
                        }
                        i = j-1;
                    }
                    break;


            }
        }
        while (!myStack.isEmpty()) {
            postfix.append(" ").append(myStack.pop());
        }
        return postfix.toString().trim();
    }
    public int getValueOfInfix(String infix){
        String postfix = infixToPostfix(infix);
        String[] items = postfix.split(" ");
        MyStack myStack = new MyStack(items.length);
        int length = items.length;
        for (int i = 0; i < length; i++) {
            String tempItem = items[i];
            switch (tempItem){
                case "+":
                    char first = myStack.pop();
                    char second = myStack.pop();
                    int result = (int)second + (int)first;
                    myStack.push((char)result);
                    break;
                case "-":
                    char first2 = myStack.pop();
                    char second2 = myStack.pop();
                    int result2 = (int)second2 - (int)first2;
                    myStack.push((char)result2);
                    break;
                case "*":
                    char first3 = myStack.pop();
                    char second3 = myStack.pop();
                    int result3 = (int)second3 * (int)first3;
                    myStack.push((char)result3);
                    break;
                case "/":
                    char first4 = myStack.pop();
                    char second4 = myStack.pop();
                    int result4 = (int)second4 / (int)first4;
                    myStack.push((char)result4);
                    break;
                //if is number.
                default:
                    int charInt = Integer.parseInt(tempItem);
                    myStack.push((char)charInt);
                    break;
            }
        }
        return myStack.pop();
    }

    /**
     * 这是一个简单的栈实现
     */
    class MyStack {
        private char[] stackArray;
        private int topIndex ;

        public MyStack(int maxSize) {
            stackArray = new char[maxSize];
            topIndex = -1;
        }
        public void push(char newTopItem){
            stackArray[++topIndex] = newTopItem;
        }
        public char pop(){
            return stackArray[topIndex--];
        }
        public char peek(){
            return stackArray[topIndex];
        }
        public boolean isEmpty(){
            return topIndex<0;
        }
    }
}
